package com.feihong.txgw.utils.client;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.feihong.txgw.app.App;
import com.feihong.txgw.http.RefreshToken;
import com.feihong.txgw.message.LoginMessage;
import com.feihong.txgw.model.base_bean.BaseResponse;
import com.feihong.txgw.ui.activity.user.LoginActivity;
import com.feihong.txgw.ui.activity.user.MyDeliveryAdrActivity;
import com.feihong.txgw.utils.CacheDataManger;
import com.feihong.txgw.utils.PreferenceTools;
import com.feihong.txgw.utils.UserLoginInfo;
import com.feihong.txgw.utils.greendao.GreenDaoOperateHelper;
import com.feihong.txgw.utils.sign.SignToken;
import com.feihong.txgw.utils.weakrefrence.StackTopActivity;

import org.greenrobot.eventbus.EventBus;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

import cn.pedant.SweetAlert.SweetAlertDialog;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

import static com.feihong.txgw.ui.activity.user.LoginActivity.isFrouceLogoutKey;

/**
 * @Author wangziheng
 * @ProjectName txgw_app
 * @ClassName TxokttpClient
 * @package com.feihong.txgw.utils.client
 * @data 2018/5/2 18:33
 * @Describe
 * @Change
 */
public class TxokttpClient extends OkHttpClient {
    private static final String TAG = "通讯顾问";
    private static OkHttpClient.Builder txokttpClient = new TxokttpClient.Builder();

    public static OkHttpClient create() {
        txokttpClient.addInterceptor(new TxInterceptors());
        return txokttpClient.build();
    }

    static class TxInterceptors implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Response resp;
            if (SignToken.isNeedSignPath(request)) {
                Request newRequest = queryNewRequest(request);
                showRequest(newRequest);
                resp = chain.proceed(newRequest);
            } else {
                resp = chain.proceed(request);
                return resp;
            }
            return checkToken(resp, chain);
        }

        /**
         * 检查token
         * @param response
         * @param chain
         * @return
         * @throws IOException
         */
        private Response checkToken(Response response, Chain chain) throws IOException {
            try {
                String responseStr = parseResponse(response);
//                Log.i("okhttpClient", "响应: "+responseStr);
                BaseResponse baseResponse;

                if(responseStr.endsWith("</html>")){
                    Log.i(TAG, "数据返回xml: "+responseStr);
                    baseResponse = new BaseResponse();
                    baseResponse.code = 301;
                    baseResponse.msg = "数据类型返回错误";
                    baseResponse.data = null;
                    String content = JSON.toJSONString(baseResponse);
                    return response.newBuilder().body(createNewResponseBody(response.body().contentType(),content)).build();
                }else {
                    baseResponse = JSON.parseObject(responseStr, BaseResponse.class);
                }
                if (4000 == (baseResponse.code)) {
                    RefreshToken.getInstance().RetrofitRefreshTokenForPost();
                    Request request = chain.request();
                    Request newRequest = queryNewRequest(request);
                    Response resp = chain.proceed(newRequest);
                    return checkToken(resp, chain);
                } else if (2001 == (baseResponse.code) && baseResponse.msg.contains("登录")) {
                    Log.i(TAG, "checkToken: token断连,需要强制退出");
                    final Activity activity = StackTopActivity.getInstance().get();
                    if(activity != null){

                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                UserLoginInfo.userExitLogin();
                                // 退出登录时  将默认收货地址的缓存清空
                                PreferenceTools.putString(MyDeliveryAdrActivity.DEFAULT_ADR_KEY, "");
                                PreferenceTools.putString("ll_info_result", "");
                                //应该把我的->用户名称 还原
                                try {
                                    CacheDataManger.getTotalCacheSize(activity).startsWith("0");
                                } catch (Exception e) {

                                }
                                LoginMessage loginMessage = new LoginMessage();
                                loginMessage.setAction(LoginMessage.ACTION_EXIT);
                                GreenDaoOperateHelper.delAll();
                                EventBus.getDefault().post(loginMessage);
                                UserLoginInfo.updateUserToken("");
                                App.getApp().lastUpdateToken = 0;
                                SweetAlertDialog mDialog = new SweetAlertDialog(activity, SweetAlertDialog.CUSTOM_IMAGE_TYPE);
                                mDialog.setTitleText(null)
                                        .setContentText("您的身份信息已失效,请重新登录")
                                        .setNeutralText("确认");
                                mDialog.setCanceledOnTouchOutside(false);
                                mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                                    @Override
                                    public void onDismiss(DialogInterface dialog) {
                                        Intent intent = new Intent(activity, LoginActivity.class);
                                        intent.putExtra(isFrouceLogoutKey,true);
                                        activity.startActivity(intent);
                                    }
                                });
                                mDialog.show();
                            }
                        });
                        baseResponse.code = 200;
                        baseResponse.data = null;
                        String content = JSON.toJSONString(baseResponse);
                        Response newResponse =  response.newBuilder().body(createNewResponseBody(response.body().contentType(),content)).build();
                        return newResponse;
                    }
                }
                return response;
            } catch (Exception e) {
                return response;
            }
        }

        /**
         * 解析Response
         * @param response
         * @return
         * @throws IOException
         */
        @NonNull
        private String parseResponse(Response response) throws IOException {
            ResponseBody responseBody = null;
            Reader jsonReader = null;
            BufferedReader reader = null;
            try {
                Charset charset;
                charset = Charset.forName("UTF-8");
                responseBody = response.peekBody(Long.MAX_VALUE);
                jsonReader = new InputStreamReader(responseBody.byteStream(), charset);
                reader = new BufferedReader(jsonReader);
                StringBuilder sbJson = new StringBuilder();
                String line = reader.readLine();
                do {
                    sbJson.append(line);
                    line = reader.readLine();
                } while (line != null);
                return sbJson.toString();
            }finally {
                if (reader != null) {
                    reader.close();
                }
                if (jsonReader != null) {
                    jsonReader.close();
                }
                if (responseBody != null) {
                    responseBody.close();
                }
            }

        }

        /**
         * 创建新的 responseBody
         * @param mediaType
         * @param content
         * @return
         */
        private ResponseBody createNewResponseBody(MediaType mediaType,String content){
            return ResponseBody.create(mediaType,content);
        }
        /**
         * 获取新请求对象
         *
         * @param request
         * @return
         */
        private Request queryNewRequest(Request request) {
            String method = request.method();
            if (method.equals("POST")) {
                RequestBody requestBody = request.body();
                RequestBody newRequestBody = null;
                if (requestBody instanceof FormBody) {
                    newRequestBody = addParamsToFormBody((FormBody) requestBody);
                    Request newRequest = request.newBuilder()
                            .url(request.url())
                            .method(request.method(), newRequestBody)
                            .build();
                    return newRequest;
                } else if (requestBody instanceof MultipartBody) {
                    return addParamsToMultipartBody((MultipartBody) requestBody, request);
                } else {
                    return createRequestForGet(request);
                }
            } else {
                return createRequestForGet(request);
            }
        }


        /**
         * 替换请求参数  创建新的请求 --->>>Post  FormBody
         *
         * @param body
         * @return
         */
        private FormBody addParamsToFormBody(FormBody body) {
            Map<String, String> mParamsmap = new HashMap<>();
            FormBody.Builder builder = new FormBody.Builder();

            for (int i = 0; i < body.size(); i++) {
                mParamsmap.put(body.encodedName(i), body.encodedValue(i));
            }
            SignToken signParams = new SignToken();
            Map<String, String> newParamsMap = signParams.setSigen(mParamsmap);
            String token = newParamsMap.get(SignToken.sToken);
            builder.add(SignToken.sData, newParamsMap.get(SignToken.sData));
            builder.add(SignToken.sSign, newParamsMap.get(SignToken.sSign));
            builder.add(SignToken.sVersion, newParamsMap.get(SignToken.sVersion));
            if (!TextUtils.isEmpty(token)) {
                builder.add(SignToken.sToken, token);
            }
//        //添加原请求体
//        for (int i = 0; i < body.size(); i++) {
//            builder.addEncoded(body.encodedName(i), body.encodedValue(i));
//        }
            return builder.build();
        }

        /**
         * 替换请求参数  创建新的请求 --->>>Post  MultipartBody
         *
         * @param body
         * @param request
         * @return
         */
        private Request addParamsToMultipartBody(MultipartBody body, Request request) {
            MultipartBody.Builder builder = new MultipartBody.Builder();
            builder.setType(MultipartBody.FORM);
            Map<String, String> multipartParams = new HashMap<>();
            HttpUrl httpUrl = HttpUrl.get(request.url().uri());
            for (int index = 0; index < httpUrl.querySize(); index++) {
                if (!"file".equals(httpUrl.queryParameterValue(index))) {
                    multipartParams.put(httpUrl.queryParameterName(index), httpUrl.queryParameterValue(index));
                }
            }
            SignToken signParams = new SignToken();
            Map<String, String> newParams = signParams.setSigen(multipartParams);
            httpUrl = request.url().newBuilder()
                    .addQueryParameter(SignToken.sData, newParams.get(SignToken.sData))
                    .addQueryParameter(SignToken.sSign, newParams.get(SignToken.sSign))
                    .addQueryParameter(SignToken.sToken, newParams.get(SignToken.sToken))
                    .addQueryParameter(SignToken.sVersion, newParams.get(SignToken.sVersion))
                    .build();
            //添加原请求体
            for (int i = 0; i < body.size(); i++) {
                builder.addPart(body.part(i));
            }
            return request.newBuilder().post(builder.build()).url(httpUrl).build();
//        return builder.build();
        }


        /**
         * 替换请求参数  创建新的请求---->>Get
         *
         * @param request
         * @return
         */
        private  Request createRequestForGet(Request request) {
            Request requestClone = request;
            HttpUrl httpUrl = HttpUrl.get(requestClone.url().uri());

            Map<String, String> requestParams = new HashMap<>();
            for (int index = 0; index < httpUrl.querySize(); index++) {
                if (!"file".equals(httpUrl.queryParameterValue(index))) {
                    requestParams.put(httpUrl.queryParameterName(index), httpUrl.queryParameterValue(index));
                }
            }
            SignToken signParams = new SignToken();
            HttpUrl mUrl = requestClone.url();
            Map<String, String> newParams = signParams.setGetSign(requestParams);
            Request newRequest = new Request.Builder()
                    .method(requestClone.method(), requestClone.body())
                    .url(mUrl.scheme() + "://" + mUrl.host() + mUrl.encodedPath()).build();
            HttpUrl newHttpUrl = newRequest.url()
                    .newBuilder()
                    .addQueryParameter(SignToken.sData, newParams.get(SignToken.sData))
                    .addQueryParameter(SignToken.sSign, newParams.get(SignToken.sSign))
                    .addQueryParameter(SignToken.sToken, newParams.get(SignToken.sToken))
                    .addQueryParameter(SignToken.sVersion, newParams.get(SignToken.sVersion))
                    .build();
            request = newRequest.newBuilder().url(newHttpUrl).build();
            return request;
        }

        private  void showRequest(Request request){
            RequestBody requestBody = request.body();
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(request.url().scheme()+"://"+request.url().host()+request.url().encodedPath()+"    ");
            if (requestBody instanceof FormBody) {
                FormBody newRequestBody = (FormBody) requestBody;
                for (int i = 0; i < newRequestBody.size(); i++) {
                    stringBuffer.append(newRequestBody.encodedName(i)+" = " + newRequestBody.encodedValue(i));
                }
            } else if (requestBody instanceof MultipartBody) {
                HttpUrl httpUrl = HttpUrl.get(request.url().uri());
                for (int index = 0; index < httpUrl.querySize(); index++) {
                    if (!"file".equals(httpUrl.queryParameterValue(index))) {
                        stringBuffer.append(httpUrl.queryParameterName(index)+" = " + httpUrl.queryParameterValue(index));
                    }
                }
            } else {
                HttpUrl httpUrl = HttpUrl.get(request.url().uri());
                for (int index = 0; index < httpUrl.querySize(); index++) {
                    if (!"file".equals(httpUrl.queryParameterValue(index))) {
                        stringBuffer.append(httpUrl.queryParameterName(index)+" = " + httpUrl.queryParameterValue(index));
                    }
                }
            }
            Log.i("请求 加密后的", "请求: "+stringBuffer);
        }
    }

}
